根據上一篇的程式碼,雖然我們達成了指定函式型別的目的,但你會發現它在閱讀性上並不是很好:
function calculate(a: number, b: number, fn: (a: number, b: number) => number) {
return fn(a, b)
}
自定義型別可以提高代碼的可讀性和重用性,尤其是在多處使用相同型別的情況下。我們可以通過將型別提取出來的方式,讓代碼更簡潔、更具結構。例如,我們可以將函式的型別定義提取出來:
type AddFn = (a: number, b: number) => number
然後在需要這個型別的地方放入:
type AddFn = (a: number, b: number) => number
function add(a: number, b: number) {
const sum = a + b
return sum
}
function calculate(a: number, b: number, fn: AddFn) {
return fn(a, b)
}
calculate(1, 2, add) // 3
自定義型別也可以用在我們先前的物件例子上。
原本程式碼如下:
let user: {
name: string
age: number
password: string | number
isAdmin: boolean
}
提取後的程式碼如下:
type User = {
name: string
age: number
password: string | number
isAdmin: boolean
}
let user: User
我們也可以將自定義型別與 Union 結合使用,這樣能夠讓變數接受多種型別的值,提升靈活性。例如:
type Password = string | number
在 TypeScript 中,為函式或物件等定義自定義型別( Custom Types
)時,通常會以大寫字母開頭。這樣做的主要原因是遵循命名慣例,以便和變數名稱區分開來,並且提高可讀性
Interface
是另一種常用的方式,用來為物件定義型別。它的語法與自定義型別 type
有些不同,主要是 Interface
不需要等號來進行定義。Interface
在 TypeScript 中主要用於物件型別定義:
interface User {
name: string
age: number
password: string | number
isAdmin: boolean
}
let user: User
並且可以通過繼承來擴展型別的結構,這邊我們以與建構子 ( constructor ) 的搭配使用為範例:
interface User {
name: string
age: number
password: string | number
isAdmin: boolean
}
class UserDetails implements User{
name: string
age: number
password: string | number
isAdmin: boolean
}
在這樣的情形下,建構子不但繼承了 User
的型別,也能夠加入額外的型別,像是下方例子中的 phoneNumber
:
interface User {
name: string
age: number
password: string | number
isAdmin: boolean
}
class UserDetails implements User{
name: string
age: number
password: string | number
isAdmin: boolean
phoneNumber: number
}
Interface
的一大優勢在於它可以通過繼承來擴展型別。我們可以使用 interface
繼承現有的型別,並在此基礎上添加新的屬性。這不僅減少了重複代碼,還使得代碼更加易於維護和擴展。
interface User {
name: string
age: number
password: string | number
isAdmin: boolean
}
interface User {
address: string
}
class UserDetails implements User{
name: string
age: number
password: string | number
isAdmin: boolean
phoneNumber: number
}
從下面的截圖可以看出,目前報錯的原因顯示為在 UserDetails
中找不到 address
這個屬性,從這個報錯可以得知,我們第二次定義的 interface
是有順利擴充的:
Custom Types (type
) 可以用於多種情境,例如函式、物件型別和 Union。相比之下,Interface
主要用於定義物件型別,並且無法像 type
那樣直接用來定義 Union 型別。雖然 Interface
在一些使用上有一定的限制,但它在物件型別的繼承與擴展上非常有優勢。
在物件型別的繼承和擴展上,Interface
表現得更加靈活。它不僅可以讓我們透過繼承避免代碼重複,還可以在大型專案中,隨著需求變更,輕鬆擴充型別。這種特性在多人協作時尤其有用。
開發者可以基於已有的 Interface
進行擴充,而不會影響現有的代碼,這樣可以保持系統的靈活性和可維護性。
綜合來看,type
和 Interface
都是強大且靈活的型別管理工具。當你需要定義聯合型別(Union)或函式型別時,type
會是更合適的選擇;而當你需要擴展物件型別並且希望代碼具有可擴充性時,Interface
則提供了更好的靈活性。